DEFINITION MODULE Coroutines;  (* J. Thoeny 4/94 *)

  TYPE
    Coroutine;
    Process;

  PROCEDURE NewCoroutine(p: PROC; n: LONGINT; VAR cID: Coroutine);
    (* create new coroutine cID, using procedure p and a workspace with size n *)

  PROCEDURE Transfer(VAR fromID, toID: Coroutine);
    (* transfer processor from coroutine fromID to coroutine toID *)

  PROCEDURE FreeCoroutineWorkspace(cID : Coroutine) : LONGINT;
    (* returns the current free workspace of coroutine cID, i.e. free stack space *)

  PROCEDURE MyCoroutineID() : Coroutine;
    (* Coroutine ID which uses the processor at the moment *)
  
  PROCEDURE NewProcess(p: PROC; n: LONGINT; VAR pID: Process);
    (* create new preemptive scheduled process pID, using procedure p and a workspace
       with size n.
       Note that the process is started in suspended State
    *)

  PROCEDURE ResumeProcess(pID: Process);
  PROCEDURE SuspendProcess(pID: Process);
  

  PROCEDURE BEGINCriticalSection();
  PROCEDURE ENDCriticalSection();

    (* disallows/allows rescheduling,
       this procedure-pair allows to perform critical tasks within a process,
       such as manipulation of global variables.

       Example:
         CONST
           MAXIterations = 10000;
         VAR
           iterationCount : INTEGER; (* is set to 1 during initialisation *)
         
         PROCEDURE MyProcess();
         BEGIN
            WHILE iterationCount < MAXIterations DO
              DoOneIteration();
              BEGINCriticalSection();
                INC(iterationCount);
              ENDCriticalSection()
            END(*WHILE*);
          END MyProcess;
    *)

  PROCEDURE MyProcessID() : Process;
    (* returns ID of the process currently using the processor*)

END Coroutines.
